<script setup lang="ts">
import { getCurrentInstance, reactive, ref, defineComponent } from 'vue'
import type { ComponentInternalInstance } from 'vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { http } from '@/http'

const { proxy } = <ComponentInternalInstance>getCurrentInstance()
interface FormData {
  pageUrl: string
  videoName: string
}
interface itemRule {
  required?: boolean
  message: string
  trigger?: string
}
interface Rules {
  pageUrl: Array<itemRule>
  videoName: Array<itemRule>
}
const message = proxy?.$message

interface msgItel {
  status: string
  content: string
}

const origin = window.location.origin
// const origin = 'http://localhost:9000'

const msgList = reactive<msgItel[]>([])

let pendding = ref<string | boolean>('')

let spinning = ref<boolean>(false)

const VNodes = defineComponent({
  props: {
    vnodes: {
      type: Object,
      required: true,
    },
  },
  render() {
    return this.vnodes
  },
})

interface videoResponse {
  videoDir?: []
  code?: number
}

const options = ref()
const inputRef = ref()
const name = ref()

http(`${origin}/getDirData`).then((res: unknown): void => {
  options.value = (res as videoResponse).videoDir?.map((item: string) => {
    return { value: item.split('/').slice(-1)[0] }
  })
})

const addItem = (e: MouseEvent | TouchEvent) => {
  e.preventDefault()

  http(`${origin}/createDir?videoName=${name.value}`).then((res: unknown) => {
    if ((res as videoResponse)?.code) {
      message.success('创建成功')
      options.value.push({ value: name.value })
    } else {
      message.error('创建失败')
    }
  })
  // items.value.push(name.value || `New item ${(index += 1)}`);
  setTimeout(() => {
    inputRef.value?.focus()
  }, 0)
}

const Form = proxy?.$Form

const useForm = Form.useForm

const formDataRef = reactive<FormData>({
  pageUrl: '',
  videoName: '',
})

const formRuleRef = reactive<Rules>({
  pageUrl: [
    {
      required: true,
      message: '请输入地址',
      trigger: 'blur',
    },
  ],
  videoName: [
    {
      required: true,
      message: '请输入视频名称',
      trigger: 'blur',
    },
  ],
})

const sse = (pageUrl: string, videoName: string): void => {
  // 创建 EventSource 对象连接服务器
  const source = new EventSource(
    `${origin}/excute?url=${pageUrl}&name=${videoName}`
  )
  // 连接成功后会触发 open 事件
  source.addEventListener(
    'open',
    () => {
      spinning.value = false
      console.log('Connected')
    },
    false
  )

  source.addEventListener(
    'doing',
    (e) => {
      pendding.value = e.data
      console.log(`data: ${e.data}`) // => data: 7
    },
    false
  )

  source.addEventListener(
    'done',
    (e) => {
      msgList.push({
        status: 'green',
        content: e.data,
      })
      console.log(`data: ${e.data}`) // => data: 7
    },
    false
  )

  source.addEventListener(
    'over',
    (e) => {
      pendding.value = false
      console.log(`data: ${e.data}`) // => data: 7
    },
    false
  )

  source.addEventListener(
    'warning',
    (e) => {
      msgList.push({
        status: 'yellow',
        content: e.data,
      })
      console.log(`data: ${e.data}`) // => data: 7
    },
    false
  )

  // 连接异常时会触发 error 事件并自动重连
  source.addEventListener(
    'error',
    (e) => {
      spinning.value = false
      const target = e.target as XMLHttpRequest
      if (target.readyState === EventSource.CLOSED) {
        console.log('Disconnected')
      } else if (target.readyState === EventSource.CONNECTING) {
        console.log('Connecting...')
      }
    },
    false
  )
}

const { validate, validateInfos } = useForm(formDataRef, formRuleRef)
const onSubmit = () => {
  validate()
    .then(() => {
      spinning.value = true
      sse(formDataRef.pageUrl, formDataRef.videoName)
    })
    .catch((err: any) => {
      console.log('error', err)
    })
}
</script>

<template>
  <a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 12 }">
    <a-form-item label="页面地址" name="pageUrl" v-bind="validateInfos.pageUrl">
      <a-input
        v-model:value="formDataRef.pageUrl"
        @blur="validate('pageUrl', { trigger: 'blur' })"
      />
    </a-form-item>
    <a-form-item
      label="视频名称"
      name="videoName"
      v-bind="validateInfos.videoName"
    >
      <a-select
        v-model:value="formDataRef.videoName"
        placeholder="选择剧名或电影名"
        :options="options"
        @blur="validate('videoName', { trigger: 'blur' })"
        @change="validate('videoName', { trigger: 'blur' })"
      >
        <template #dropdownRender="{ menuNode: menu }">
          <v-nodes :vnodes="menu" />
          <a-divider style="margin: 4px 0" />
          <a-space style="padding: 4px 8px">
            <a-input
              ref="inputRef"
              v-model:value="name"
              placeholder="请输入剧名或电影名"
            />
            <a-button type="text" @click="addItem">
              <template #icon>
                <plus-outlined />
              </template>
              新增目录
            </a-button>
          </a-space>
        </template></a-select
      >
    </a-form-item>
    <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
      <a-button type="primary" @click.prevent="onSubmit">开始执行</a-button>
    </a-form-item>
    <a-spin :spinning="spinning">
      <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
        <a-timeline :pending="pendding">
          <a-timeline-item
            :color="item.status"
            v-for="(item, index) in msgList"
            :key="index"
            ><div v-html="item.content"></div
          ></a-timeline-item>
        </a-timeline>
      </a-form-item>
    </a-spin>
  </a-form>
</template>

<style lang="less" scoped></style>
